home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / GLX / basics / kbecho.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  12.2 KB  |  440 lines

  1. /*
  2.  * Copyright 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /** header ******************************************************************/
  18.  
  19. /*
  20.  * $Source$
  21.  * $Revision$
  22.  * $Date$
  23.  * $Author$
  24.  *
  25.  * creator: Brett Bainter
  26.  *
  27.  * purpose:
  28.  *    mixed model program demonstrating
  29.  *    ...how to get continuous pointer motion events for a gl widget.
  30.  *    ...how to get keyboard events for a gl widget in a widget heirarchy.
  31.  *    ...how to map most keyboard keys to an appropriate string rep.
  32.  *
  33.  * compiling:
  34.  *    cc -float -prototypes -O kbecho.c -o kbecho \
  35.  *    -s -lXirisw -lXm_s -lXt_s -lgl_s -lX11_s -lm -lc_s -lPW
  36.  *
  37.  * operating:
  38.  *    The gl widget will automatically get keyboard events when the cursor
  39.  *    is over it.  You don't need to click in it or tab to it, though it can
  40.  *    be setup this way.
  41.  *
  42.  */
  43.  
  44. /** notes *******************************************************************/
  45. /** includes ****************************************************************/
  46.  
  47. #include <stdio.h>            /* standard */
  48. #include <Xm/Xm.h>            /* for motif */
  49. #include <Xm/Form.h>            /* motif widget */
  50. #include <Xm/Frame.h>            /* motif widget */
  51. #include <Xm/PushB.h>            /* motif widget */
  52. #include <Xm/RowColumn.h>        /* motif widget */
  53. #include <Xm/Separator.h>        /* motif widget */
  54. #include <X11/Xirisw/GlxMDraw.h>    /* gl widget */
  55.  
  56. /** defines *****************************************************************/
  57.  
  58. /* c environment */
  59. #define global
  60.  
  61. /* colors */
  62. #define RGB_BLACK    0x00000000
  63. #define RGB_RED        0x000000FF
  64. #define RGB_GREEN    0x0000FF00
  65. #define RGB_BLUE    0x00FF0000
  66.  
  67. /** typedefs ****************************************************************/
  68. /** prototypes **************************************************************/
  69.  
  70. extern void main(int argc, char *argv[], char *envp[]);
  71.  
  72. /* setup */
  73. static void install_colormaps(Widget top_level, Widget glw);
  74.  
  75. /* mixed model support */
  76. static void cb_gl_expose(Widget w, XtPointer client_data, XtPointer call_data);
  77. static void cb_gl_resize(Widget w, XtPointer client_data, XtPointer call_data);
  78. static void cb_gl_ginit(Widget w, XtPointer client_data, XtPointer call_data);
  79. static void cb_gl_input(Widget w, XtPointer client_data, XtPointer call_data);
  80.  
  81. /* callbacks (misc) */
  82. static void cb_quit(Widget w, XtPointer client_data, XtPointer call_data);
  83.  
  84. /* etc */
  85. static void draw_frame(Bool do_clear, Bool do_swap);
  86. static void xbutton_print(XEvent *event);
  87. static char *keycode_to_string(XEvent *event);
  88.  
  89. /** variables ***************************************************************/
  90.  
  91. /*
  92.  * mixed-model configuration:
  93.  */
  94. static GLXconfig glx_config[] = {
  95.     {GLX_NORMAL, GLX_DOUBLE, TRUE},
  96.     {GLX_NORMAL, GLX_RGB, TRUE},
  97.     {GLX_NORMAL, GLX_ZSIZE, GLX_NOCONFIG},
  98.     { 0, 0, 0 },
  99. };
  100.  
  101. /** functions ***************************************************************/
  102.  
  103. /*
  104.  * main - program entry point.
  105.  */
  106. global void main(
  107.     int argc,            /* argument count */
  108.     char *argv[],        /* argument vector */
  109.     char *envp[]        /* environment pointer */
  110. )
  111. {
  112.     XtAppContext app_context;    /* application context */
  113.     Display *dsp;        /* display ref */
  114.     Widget app_shell;        /* first widget */
  115.     Widget form;        /* surrounds app */
  116.     Widget rowcol;        /* manages input buttons */
  117.     Widget button;        /* quit button */
  118.     Widget separator;        /* between input and output */
  119.     Widget frame;        /* to surround gl widget */
  120.     Widget glw;            /* the gl widget inside window */
  121.     Arg args[15];        /* for name/value pairs */
  122.     int n;            /* for reusable indices */
  123.  
  124.     /* initialize toolkit, creating application shell */
  125.     n = 0;
  126.     XtSetArg(args[n], XmNtitle, "KB Echo"); n++;
  127.     app_shell = XtAppInitialize(
  128.     &app_context, "Kbecho", NULL, 0, &argc, argv, NULL, args, n
  129.     );
  130.  
  131.     /* create container for app */
  132.     n = 0;
  133.     form = XmCreateForm(app_shell, "form", args, n);
  134.     XtManageChild(form);
  135.  
  136.     /* create the command area */
  137.     n = 0;
  138.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  139.     XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  140.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  141.     XtSetArg(args[n], XmNorientation, XmVERTICAL); n++;
  142.     rowcol = XmCreateRowColumn(form, "rowcol", args, n);
  143.     XtManageChild(rowcol);
  144.  
  145.     /* create the command area buttons */
  146.     n = 0;
  147.     button = XmCreatePushButton(rowcol, "Quit", args, n);
  148.     XtAddCallback(button, XmNactivateCallback, cb_quit, NULL);
  149.     XtManageChild(button);
  150.  
  151.     /* create separator between command area and output area */
  152.     n = 0;
  153.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  154.     XtSetArg(args[n], XmNleftWidget, rowcol); n++;
  155.     XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  156.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  157.     XtSetArg(args[n], XmNorientation, XmVERTICAL); n++;
  158.     separator = XmCreateSeparator(form, "separator", args, n);
  159.     XtManageChild(separator);
  160.  
  161.     /* create the output area */
  162.     /* create the frame */
  163.     n = 0;
  164.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  165.     XtSetArg(args[n], XmNleftWidget, separator); n++;
  166.     XtSetArg(args[n], XmNleftOffset, 5); n++;
  167.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  168.     XtSetArg(args[n], XmNrightOffset, 5); n++;
  169.     XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  170.     XtSetArg(args[n], XmNbottomOffset, 5); n++;
  171.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  172.     XtSetArg(args[n], XmNtopOffset, 5); n++;
  173.     XtSetArg(args[n], XmNshadowThickness, 6); n++;
  174.     frame = XmCreateFrame(form, "frame", args, n);
  175.     XtManageChild(frame);
  176.  
  177.     /* create the gl widget */
  178.     n = 0;
  179.     XtSetArg(args[n], GlxNglxConfig, glx_config); n++;
  180.     XtSetArg(args[n], XmNtraversalOn, True); n++;
  181.     XtSetArg(args[n], XmNborderWidth, 0); n++;
  182.     XtSetArg(args[n], XmNwidth, 400); n++;
  183.     XtSetArg(args[n], XmNheight, 400); n++;
  184.     glw = GlxCreateMDraw(frame, "glw", args, n);
  185.     XtManageChild(glw);
  186.     XtAddCallback(glw, GlxNexposeCallback, cb_gl_expose, 0);
  187.     XtAddCallback(glw, GlxNresizeCallback, cb_gl_resize, 0);
  188.     XtAddCallback(glw, GlxNginitCallback, cb_gl_ginit, 0);
  189.     XtAddCallback(glw, GlxNinputCallback, cb_gl_input, 0);
  190.  
  191.     /* realize the app, creating the actual x windows */
  192.     XtRealizeWidget(app_shell);
  193.     install_colormaps(app_shell, glw);
  194.  
  195.     /* enter the event loop */
  196.     XtAppMainLoop(app_context);
  197. }
  198.  
  199.  
  200. /*- support: setup ---------------------------------------------------------*/
  201. /*
  202.  * install_colormaps - let the window manager know about our colormaps.
  203.  */
  204. static void install_colormaps(Widget top_level, Widget glw)
  205. {
  206.     Window overlay_win, popup_win, underlay_win;
  207.     Window window[5];
  208.     int i;
  209.  
  210.     XtVaGetValues(
  211.     glw,
  212.     GlxNoverlayWindow, &overlay_win,
  213.     GlxNpopupWindow, &popup_win,
  214.     GlxNunderlayWindow, &underlay_win,
  215.     NULL
  216.     );
  217.     i = 0;
  218.     if (overlay_win)
  219.     window[i++] = overlay_win;
  220.     if (popup_win)
  221.     window[i++] = popup_win;
  222.     if (underlay_win)
  223.     window[i++] = underlay_win;
  224.     window[i++] = XtWindow(glw);
  225.     window[i++] = XtWindow(top_level);
  226.     XSetWMColormapWindows(XtDisplay(top_level), XtWindow(top_level), window, i);
  227. }
  228.  
  229.  
  230. /*- support: callbacks (gl widget) -----------------------------------------*/
  231. /*
  232.  * cb_gl_expose - handle expose events for the gl widget.
  233.  */
  234. static void cb_gl_expose(Widget w, XtPointer client_data, XtPointer call_data)
  235. {
  236.     GlxDrawCallbackStruct *glx = (GlxDrawCallbackStruct *) call_data;
  237.  
  238.     printf("cb_gl_expose()\n");
  239.     GLXwinset(XtDisplay(w), XtWindow(w));
  240.     draw_frame(TRUE, TRUE);
  241. }
  242.  
  243.  
  244. /*
  245.  * cb_gl_resize - handle resize events for the gl widget.
  246.  */
  247. static void cb_gl_resize(Widget w, XtPointer client_data, XtPointer call_data)
  248. {
  249.     GlxDrawCallbackStruct *glx = (GlxDrawCallbackStruct *) call_data;
  250.  
  251.     printf("cb_gl_resize()\n");
  252.     GLXwinset(XtDisplay(w), XtWindow(w));
  253.     viewport(0, glx->width-1, 0, glx->height-1);
  254. }
  255.  
  256.  
  257. /*
  258.  * cb_gl_ginit - perform any necessary graphics initialization.
  259.  */
  260. static void cb_gl_ginit(Widget w, XtPointer client_data, XtPointer call_data)
  261. {
  262.     GlxDrawCallbackStruct *glx = (GlxDrawCallbackStruct *) call_data;
  263.  
  264.     printf("cb_gl_ginit()\n");
  265.     GLXwinset(XtDisplay(w), XtWindow(w));
  266.  
  267.     /* add pointer motion events and enter/leave events */
  268.     XSelectInput(
  269.     XtDisplay(w), XtWindow(w), XtBuildEventMask(w) | PointerMotionMask |
  270.     EnterWindowMask | LeaveWindowMask
  271.     );
  272.     XtAugmentTranslations(
  273.     w,
  274.     XtParseTranslationTable(
  275.         "<MotionNotify>: glxInput() \n\ "
  276.         "<EnterWindow>: glxInput() \n\ "
  277.         "<LeaveWindow>: glxInput()"
  278.     )
  279.     );
  280.  
  281.     mmode(MVIEWING);
  282.     ortho2(0.0, 100.0, 0.0, 100.0);
  283.     gflush();
  284. }
  285.  
  286.  
  287. /*
  288.  * cb_gl_input - handle input from a gl window.
  289.  */
  290. static void cb_gl_input(Widget w, XtPointer client_data, XtPointer call_data)
  291. {
  292.     GlxDrawCallbackStruct *glx = (GlxDrawCallbackStruct *) call_data;
  293.     XEvent *event;
  294.  
  295.     GLXwinset(XtDisplay(w), XtWindow(w));
  296.     printf("cb_gl_input( ");
  297.     event = glx->event;
  298.     switch (event->type) {
  299.     case ButtonPress:
  300.     printf("ButtonPress  (");
  301.     xbutton_print(event);
  302.     printf(")");
  303.     break;
  304.     case ButtonRelease:
  305.     printf("ButtonRelease(");
  306.     xbutton_print(event);
  307.     printf(")");
  308.     break;
  309.     case KeyPress:
  310.     printf("KeyPress  (%s)", keycode_to_string(event));
  311.     break;
  312.     case KeyRelease:
  313.     printf("KeyRelease(%s)", keycode_to_string(event));
  314.     break;
  315.     case MotionNotify:
  316.     printf("MotionNotify(%d, %d)", event->xmotion.x, event->xmotion.y);
  317.     break;
  318.     case EnterNotify:
  319.     printf("EnterNotify");
  320.     XmProcessTraversal(w, XmTRAVERSE_CURRENT);
  321.     break;
  322.     case LeaveNotify:
  323.     printf("LeaveNotify");
  324.     XmProcessTraversal(w, XmTRAVERSE_PREV_TAB_GROUP);
  325.     break;
  326.     default:
  327.     printf("UnknownEventType(%d)", event->type);
  328.     break;
  329.     }
  330.     printf(" )\n");
  331. }
  332.  
  333.  
  334. /*- support: callbacks (misc) ----------------------------------------------*/
  335. /*
  336.  * cb_quit - exit application.
  337.  */
  338. static void cb_quit(Widget w, XtPointer client_data, XtPointer call_data)
  339. {
  340.     exit(0);
  341. }
  342.  
  343.  
  344. /*- support: drawing -------------------------------------------------------*/
  345. /*
  346.  * draw_frame -
  347.  */
  348. static void draw_frame(Bool do_clear, Bool do_swap)
  349. {
  350.     static float vert[][2] = {    /* a box */
  351.     { 0.0,  0.0},
  352.     {20.0,  0.0},
  353.     {20.0, 20.0},
  354.     { 0.0, 20.0},
  355.     };
  356.  
  357.     if (do_clear) {
  358.     cpack(RGB_BLACK);
  359.     clear();
  360.     }
  361.  
  362.     pushmatrix();
  363.     translate(15.0, 40.0, 0.0);
  364.     cpack(RGB_RED);
  365.     bgnpolygon();
  366.     v2f(vert[0]);
  367.     v2f(vert[1]);
  368.     v2f(vert[2]);
  369.     v2f(vert[3]);
  370.     endpolygon();
  371.     translate(25.0, 0.0, 0.0);
  372.     cpack(RGB_GREEN);
  373.     bgnpolygon();
  374.     v2f(vert[0]);
  375.     v2f(vert[1]);
  376.     v2f(vert[2]);
  377.     v2f(vert[3]);
  378.     endpolygon();
  379.     translate(25.0, 0.0, 0.0);
  380.     cpack(RGB_BLUE);
  381.     bgnpolygon();
  382.     v2f(vert[0]);
  383.     v2f(vert[1]);
  384.     v2f(vert[2]);
  385.     v2f(vert[3]);
  386.     endpolygon();
  387.     popmatrix();
  388.  
  389.     if (do_swap) {
  390.     swapbuffers();
  391.     gflush();
  392.     }
  393. }
  394.  
  395.  
  396. /*- support: echoing keys/buttons ------------------------------------------*/
  397. /*
  398.  * xbutton_print -
  399.  */
  400. static void xbutton_print(XEvent *event)
  401. {
  402.     char *str;
  403.  
  404.     switch (event->xbutton.button) {
  405.     case Button1: str = "Button1"; break;
  406.     case Button2: str = "Button2"; break;
  407.     case Button3: str = "Button3"; break;
  408.     case Button4: str = "Button4"; break;
  409.     case Button5: str = "Button5"; break;
  410.     default:      str = "Button?"; break;
  411.     }
  412.     printf("%s", str);
  413. }
  414.  
  415.  
  416. /*
  417.  * keycode_to_string -
  418.  */
  419. static char *keycode_to_string(XEvent *event)
  420. {
  421.     #define KEYSTR_SIZE    100
  422.     static char keystr[KEYSTR_SIZE+1];
  423.     /**/
  424.     KeySym keysym;
  425.     int count;
  426.     char *tmp;
  427.  
  428.     count = XLookupString(
  429.     (XKeyEvent *) event, keystr, KEYSTR_SIZE, &keysym, NULL
  430.     );
  431.     keystr[count] = '\0';
  432.     if (count == 0) {
  433.     tmp = XKeysymToString(keysym);
  434.     strcpy(keystr, tmp!=NULL? tmp : "");
  435.     }
  436.     return (keystr);
  437. }
  438.  
  439. /** eof *********************************************************************/
  440.